package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.wxpay.sdk.Config;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import com.qingcheng.service.order.OrderService;
import com.qingcheng.service.order.WxPayService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.Map;

@Service
public class WxPayServiceImpl implements WxPayService {
    @Autowired
    private Config config;


    /**
     * 生成微信支付二维码
     *
     * @param orderId   订单号
     * @param money     金额
     * @param notifyUrl 回调地址
     * @return
     */
    @Override
    public Map createNative(String orderId, Integer money, String notifyUrl) {

        try {
            //生成参数
            Map<String, String> param = new HashMap<>(); //创建参数
            param.put("appid", config.getAppID()); //公众号
            param.put("mch_id", config.getMchID()); //商户号
            param.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串
            param.put("body", "青橙"); //商品描述
            param.put("out_trade_no", orderId); //订单号
            param.put("total_fee", money + ""); //金额
            param.put("spbill_create_ip", "127.0.0.1"); //终端ip
            param.put("notify_url", notifyUrl); //通知地址
            param.put("trade_type", "NATIVE"); //交易类型
            String xmlParam = WXPayUtil.generateSignedXml(param, config.getKey());
            //发送请求
            WXPayRequest wxPayRequest = new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/unifiedorder", null, xmlParam, false);
            System.out.println("结果:" + xmlResult);
            //往延迟消息队列中发送订单号
            rabbitTemplate.convertAndSend("","queue.ordercreate",orderId+"");
            //解析返回结果
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            Map map = new HashMap();
            map.put("code_url", mapResult.get("code_url")); //支付地址
            map.put("total_fee", money + ""); //总金额
            map.put("out_trade_no", orderId); //订单号

            return map;

        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap();
        }
    }

    /**
     * 微信支付api查询订单号，查看订单是否支付成功
     * @param orderId
     * @return
     */
    public Boolean findNative(String orderId){
        try {
            //生成参数
            Map<String, String> param = new HashMap<>(); //创建参数
            param.put("appid", config.getAppID()); //公众号
            param.put("mch_id", config.getMchID()); //商户号
            param.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串
            param.put("out_trade_no", orderId); //订单号
            String xmlParam = WXPayUtil.generateSignedXml(param, config.getKey());//签名
            //发送请求
            WXPayRequest wxPayRequest = new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/orderquery", null, xmlParam, false);
            System.out.println("结果:" + xmlResult);
            //解析返回结果
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            if(orderId!=null){

            //判断支付是否成功
            boolean trade_state = "SUCCESS".equals(mapResult.get("trade_state"));
            System.out.println("订单是否支付成功"+trade_state);
            return trade_state;
            }else {
                return null;
            }
           /* return mapResult;*/

        } catch (Exception e) {
            e.printStackTrace();
            /*return new HashMap();*/
            return null;
        }
    }

    /**
     * 微信支付api关闭订单号，查看订单是否关闭成功
     * @param orderId
     * @return
     */
    public Boolean closeNative(String orderId){
        try {
            //生成参数
            Map<String, String> param = new HashMap<>(); //创建参数
            param.put("appid", config.getAppID()); //公众号
            param.put("mch_id", config.getMchID()); //商户号
            param.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串
            param.put("out_trade_no", orderId); //订单号
            String xmlParam = WXPayUtil.generateSignedXml(param, config.getKey());
            //发送请求
            WXPayRequest wxPayRequest = new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/closeorder", null, xmlParam, false);
            System.out.println("结果:" + xmlResult);
            //往延迟消息队列中发送订单号
            rabbitTemplate.convertAndSend("","queue.ordercreate",orderId+"");
            //解析返回结果
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            //判断是否成功关闭订单
            if(orderId!=null) {
                boolean result_code = "SUCCESS".equals(mapResult.get("result_code"));
                System.out.println("订单是否关闭" + result_code);
                return result_code;
                /*return mapResult;*/
            }else{
                return null;
            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
            /*return new HashMap();*/
        }
    }

    @Autowired
    private OrderService orderService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 微信支付回调
     *
     * @param xml
     */
    @Override
    public void notifyLogic(String xml) {
        try {
            //对xml解析成map
            Map<String, String> map = WXPayUtil.xmlToMap(xml);
            //验证签名
            boolean signatureValid = WXPayUtil.isSignatureValid(map, config.getKey());
            System.out.println("验证签名是否正确:" + signatureValid);
            System.out.println(map.get("out_trade_no")); //订单号
            System.out.println(map.get("transaction_id")); //流水号
            System.out.println(map.get("result_code"));
            //更新订单状态
            if("SUCCESS".equals(map.get("result_code"))) {
                orderService.updatePayStatus(map.get("out_trade_no"), map.get("transaction_id"));
                rabbitTemplate.convertAndSend("paynotify","",map.get("out_trade_no"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
